home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / bin / purple-remote < prev    next >
Encoding:
Text File  |  2009-08-19  |  7.8 KB  |  241 lines

  1. #!/usr/bin/env python
  2.  
  3. import dbus
  4. import re
  5. import urllib
  6. import sys
  7.  
  8. import xml.dom.minidom 
  9.  
  10. xml.dom.minidom.Element.all   = xml.dom.minidom.Element.getElementsByTagName
  11.  
  12. obj = None
  13. try:
  14.     obj = dbus.SessionBus().get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
  15. except:
  16.     pass
  17.  
  18. purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
  19.  
  20. class CheckedObject:
  21.     def __init__(self, obj):
  22.         self.obj = obj
  23.  
  24.     def __getattr__(self, attr):
  25.         return CheckedAttribute(self, attr)
  26.  
  27. class CheckedAttribute:
  28.     def __init__(self, cobj, attr):
  29.         self.cobj = cobj
  30.         self.attr = attr
  31.         
  32.     def __call__(self, *args):
  33.         result = self.cobj.obj.__getattr__(self.attr)(*args)
  34.         if result == 0:
  35.             raise "Error: " + self.attr + " " + str(args) + " returned " + str(result)
  36.         return result
  37.             
  38. def show_help(requested=False):
  39.     print """This program uses D-Bus to communicate with purple.
  40.  
  41. Usage:
  42.  
  43.     %s "command1" "command2" ...
  44.  
  45. Each command is of one of the three types:
  46.  
  47.     [protocol:]commandname?param1=value1¶m2=value2&...
  48.     FunctionName?param1=value1¶m2=value2&...
  49.     FunctionName(value1,value2,...)
  50.  
  51. The second and third form are provided for completeness but their use
  52. is not recommended; use purple-send or purple-send-async instead.  The
  53. second form uses introspection to find out the parameter names and
  54. their types, therefore it is rather slow.
  55.  
  56. Examples of commands:
  57.  
  58.     jabber:goim?screenname=testone@localhost&message=hi
  59.     jabber:gochat?room=TestRoom&server=conference.localhost
  60.     jabber:getinfo?screenname=testone@localhost
  61.     jabber:addbuddy?screenname=my friend
  62.  
  63.     setstatus?status=away&message=don't disturb
  64.     getstatus
  65.     getstatusmessage
  66.     quit
  67.  
  68.     PurpleAccountsFindConnected?name=&protocol=prpl-jabber
  69.     PurpleAccountsFindConnected(,prpl-jabber)
  70. """ % sys.argv[0]
  71.     if (requested):
  72.         sys.exit(0)
  73.     else:
  74.         sys.exit(1)
  75.  
  76. cpurple = CheckedObject(purple)
  77.  
  78. urlregexp = r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?"
  79.  
  80. def extendlist(list, length, fill):
  81.     if len(list) < length:
  82.         return list + [fill] * (length - len(list))
  83.     else:
  84.         return list
  85.  
  86. def convert(value):
  87.     try:
  88.         return int(value)
  89.     except:
  90.         return value
  91.  
  92. def findaccount(accountname, protocolname):
  93.     try:
  94.         # prefer connected accounts
  95.         account = cpurple.PurpleAccountsFindConnected(accountname, protocolname)
  96.         return account
  97.     except:
  98.         # try to get any account and connect it
  99.         account = cpurple.PurpleAccountsFindAny(accountname, protocolname)
  100.         purple.PurpleAccountSetStatusVargs(account, "online", 1)
  101.         purple.PurpleAccountConnect(account)
  102.         return account
  103.     
  104.  
  105. def execute(uri):
  106.     match = re.match(urlregexp, uri)
  107.     protocol = match.group(2)
  108.     if protocol == "xmpp":
  109.         protocol = "jabber"
  110.     if protocol is not None:
  111.         protocol = "prpl-" + protocol
  112.     command = match.group(5)
  113.     paramstring = match.group(7)
  114.     params = {}
  115.     if paramstring is not None:
  116.         for param in paramstring.split("&"):
  117.             key, value = extendlist(param.split("=",1), 2, "")
  118.             params[key] = urllib.unquote(value)
  119.  
  120.     accountname = params.get("account", "")
  121.  
  122.     if command == "goim":
  123.         account = findaccount(accountname, protocol)
  124.         conversation = cpurple.PurpleConversationNew(1, account, params["screenname"])
  125.         if "message" in params:
  126.             im = cpurple.PurpleConversationGetImData(conversation)
  127.             purple.PurpleConvImSend(im, params["message"])
  128.         return None
  129.  
  130.     elif command == "gochat":
  131.         account = findaccount(accountname, protocol)
  132.         connection = cpurple.PurpleAccountGetConnection(account)
  133.         return purple.ServJoinChat(connection, params)
  134.  
  135.     elif command == "addbuddy":
  136.         account = findaccount(accountname, protocol)
  137.         return cpurple.PurpleBlistRequestAddBuddy(account, params["screenname"],
  138.                                               params.get("group", ""), "")
  139.  
  140.     elif command == "setstatus":
  141.         current = purple.PurpleSavedstatusGetCurrent()
  142.  
  143.         if "status" in params:
  144.             status_id = params["status"]
  145.             status_type = purple.PurplePrimitiveGetTypeFromId(status_id)
  146.         else:
  147.             status_type = purple.PurpleSavedstatusGetType(current)
  148.             status_id = purple.PurplePrimitiveGetIdFromType(status_type)
  149.  
  150.         if "message" in params:
  151.             message = params["message"];
  152.         else:
  153.             message = purple.PurpleSavedstatusGetMessage(current)
  154.  
  155.         if "account" in params:
  156.             accounts = [cpurple.PurpleAccountsFindAny(accountname, protocol)]
  157.  
  158.             for account in accounts:
  159.                 status = purple.PurpleAccountGetStatus(account, status_id)
  160.                 type = purple.PurpleStatusGetType(status)
  161.                 purple.PurpleSavedstatusSetSubstatus(current, account, type, message)
  162.                 purple.PurpleSavedstatusActivateForAccount(current, account)
  163.         else:
  164.             accounts = purple.PurpleAccountsGetAllActive()
  165.             saved = purple.PurpleSavedstatusNew("", status_type)
  166.             purple.PurpleSavedstatusSetMessage(saved, message)
  167.             purple.PurpleSavedstatusActivate(saved)
  168.  
  169.         return None
  170.  
  171.     elif command == "getstatus":
  172.         current = purple.PurpleSavedstatusGetCurrent()
  173.         status_type = purple.PurpleSavedstatusGetType(current)
  174.         status_id = purple.PurplePrimitiveGetIdFromType(status_type)
  175.         return status_id
  176.  
  177.     elif command == "getstatusmessage":
  178.         current = purple.PurpleSavedstatusGetCurrent()
  179.         return purple.PurpleSavedstatusGetMessage(current)
  180.  
  181.     elif command == "getinfo":
  182.         account = findaccount(accountname, protocol)
  183.         connection = cpurple.PurpleAccountGetConnection(account)
  184.         return purple.ServGetInfo(connection, params["screenname"])
  185.  
  186.     elif command == "quit":
  187.         return purple.PurpleCoreQuit()
  188.  
  189.     elif command == "uri":
  190.         return None
  191.  
  192.     else:
  193.         match = re.match(r"(\w+)\s*\(([^)]*)\)", command)
  194.         if match is not None:
  195.             name = match.group(1)
  196.             argstr = match.group(2)
  197.             if argstr == "":
  198.                 args = []
  199.             else:
  200.                 args = argstr.split(",")
  201.             fargs = []
  202.             for arg in args:
  203.                 fargs.append(convert(arg.strip()))
  204.             return purple.__getattr__(name)(*fargs)
  205.         else:
  206.             # introspect the object to get parameter names and types
  207.             # this is slow because the entire introspection info must be downloaded
  208.             data = dbus.Interface(obj, "org.freedesktop.DBus.Introspectable").\
  209.                    Introspect()
  210.             introspect = xml.dom.minidom.parseString(data).documentElement
  211.             for method in introspect.all("method"):
  212.                 if command == method.getAttribute("name"):
  213.                     methodparams = []
  214.                     for arg in method.all("arg"):
  215.                         if arg.getAttribute("direction") == "in":
  216.                             value = params[arg.getAttribute("name")]
  217.                             type = arg.getAttribute("type")
  218.                             if type == "s":
  219.                                 methodparams.append(value)
  220.                             elif type == "i":
  221.                                 methodparams.append(int(value))
  222.                             else:
  223.                                 raise "Don't know how to handle type \"%s\"" % type
  224.                     return purple.__getattr__(command)(*methodparams)
  225.             show_help()
  226.  
  227. if len(sys.argv) == 1:
  228.     show_help()
  229. elif (sys.argv[1] == "--help" or sys.argv[1] == "-h"):
  230.     show_help(True)
  231. elif (obj == None):
  232.     print "No existing libpurple instance detected."
  233.     sys.exit(1);
  234.     
  235. for arg in sys.argv[1:]:
  236.     output = execute(arg)
  237.  
  238.     if (output != None):
  239.         print output
  240.  
  241.